package com.lianxi.util;

import com.lianxi.constant.ExportConstant;
import com.lianxi.dto.ExportPdfDto;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.font.FontProvider;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Date  : 2016/7/21 10:55
 */
public class ExportUtil<T> {

    private static final String REG01 = "^//d+(//.//d+)?$";
    private static final String REG02 = "^//d+(//.//d+)?$";
    private static final String FONT_RESOURCE_DIR = "/font";
    private static final String PDF_DIR = "/pdf";


//    public void exportExcelnews(String[] headers, Collection<T> dataset,
//                                OutputStream out) {
//        exportExcelnews("统计", headers, dataset, out, "yyyy-MM-dd HH:mm:ss");
//    }
//
//    /**
//     * 修改一些表格长度
//     * @param title   表格标题名
//     * @param headers 表格属性列名数组
//     * @param dataset 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
//     *                javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
//     * @param out     与输出设备关联的流对象，可以将EXCEL文档导出到本地文件或者网络中
//     * @param pattern 如果有时间数据，设定输出格式。默认为"yyy-MM-dd"
//     */
//    @SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
//    public void exportExcelnews(String title, String[] headers,
//                                Collection<T> dataset, OutputStream out, String pattern) {
//        // 声明一个工作薄
//        HSSFWorkbook workbook = new HSSFWorkbook();
//        // 生成一个表格
//        HSSFSheet sheet = workbook.createSheet(title);
//        // 设置表格默认列宽度为15个字节
/////        sheet.setDefaultColumnWidth((short) 15);
//
//        sheet.setColumnWidth(0, 15000);
//        sheet.setColumnWidth(1, 5000);
//        sheet.setColumnWidth(2, 12000);
//        sheet.setColumnWidth(3, 5000);
//
//        // 生成一个样式
//        HSSFCellStyle style = workbook.createCellStyle();
//        // 设置这些样式
//        style.setFillForegroundColor(
//                HSSFColor.DARK_BLUE.index);
//        style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//        style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
//        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
//        style.setBorderRight(HSSFCellStyle.BORDER_THIN);
//        style.setBorderTop(HSSFCellStyle.BORDER_THIN);
//        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//        // 生成一个字体
//        HSSFFont font = workbook.createFont();
//        font.setColor(HSSFColor.WHITE.index);
//        font.setFontHeightInPoints((short) 16);
//        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
//        // 把字体应用到当前的样式
//        style.setFont(font);
//        // 生成并设置另一个样式
//        HSSFCellStyle style2 = workbook.createCellStyle();
//        style2.setFillForegroundColor(
//                HSSFColor.WHITE.index);
//        style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//        style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
//        style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
//        style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
//        style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
//        style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//        style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//        // 生成另一个字体
//        HSSFFont font2 = workbook.createFont();
//        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
//        font2.setFontHeightInPoints((short) 11);
//        // 把字体应用到当前的样式
//        style2.setFont(font2);
//
//        // 声明一个画图的顶级管理器
//        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
//        // 定义注释的大小和位置,详见文档
//        HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0,
//                0, 0, 0, (short) 4, 2, (short) 6, 5));
//        // 设置注释内容
//        comment.setString(new HSSFRichTextString("可以在POI中添加注释！"));
//        // 设置注释作者，当鼠标移动到单元格上是可以在状态栏中看到该内容.
//        comment.setAuthor("leno");
//
//        // 产生表格标题行
//        HSSFRow row = sheet.createRow(0);
//        for (short i = 0; i < headers.length; i++) {
//            HSSFCell cell = row.createCell(i);
//            cell.setCellStyle(style);
//            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
//            sheet.setColumnWidth((short) 0, (short) (20 * 200));
//            sheet.setColumnWidth((short) 1, (short) (20 * 500));
//            sheet.setColumnWidth((short) 2, (short) (20 * 300));
//            sheet.setColumnWidth((short) 3, (short) (20 * 300));
//            sheet.setColumnWidth((short) 4, (short) (20 * 300));
//            sheet.setColumnWidth((short) 5, (short) (20 * 300));
//            sheet.setColumnWidth((short) 6, (short) (20 * 300));
//
//
//            cell.setCellValue(text);
//        }
//
//        // 遍历集合数据，产生数据行
//        Iterator<T> it = dataset.iterator();
//        int index = 0;
//        while (it.hasNext()) {
//            index++;
//            row = sheet.createRow(index);
//            T t = it.next();
//            // 利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
//            Field[] fields = t.getClass().getDeclaredFields();
//            for (short i = 0; i < fields.length; i++) {
//                HSSFCell cell = row.createCell(i);
//                cell.setCellStyle(style2);
//                Field field = fields[i];
//                String fieldName = field.getName();
//                String getMethodName = "get"
//                        + fieldName.substring(0, 1).toUpperCase()
//                        + fieldName.substring(1);
//                try {
//                    Class tCls = t.getClass();
//                    Method getMethod = tCls.getMethod(getMethodName
//                    );
//                    Object value = getMethod.invoke(t);
//                    // 判断值的类型后进行强制类型转换
//                    String textValue = null;
//                    if (value instanceof Integer) {
//                        int intValue = (Integer) value;
//                        cell.setCellValue(intValue);
//                    } else if (value instanceof Float) {
//                        float fValue = (Float) value;
//                        textValue = String.valueOf(fValue);
//                        cell.setCellValue(textValue);
//                    } else if (value instanceof Double) {
//                        double dValue = (Double) value;
//                        textValue = String.valueOf(dValue);
//                        cell.setCellValue(textValue);
//                    } else if (value instanceof Long) {
//                        long longValue = (Long) value;
//                        cell.setCellValue(longValue);
//                    } else if (value instanceof Date) {
//                        Date date = (Date) value;
//                        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
//                        textValue = sdf.format(date);
//                        cell.setCellValue(textValue);
//                    } else if (value instanceof String) {
//                        cell.setCellValue((String) value);
//                    }
//                    if (textValue != null) {
//                        Pattern p = Pattern.compile(REG02);
//                        Matcher matcher = p.matcher(textValue);
//                        if (matcher.matches()) {
//                            // 是数字当作double处理
//                            cell.setCellValue(Double.parseDouble(textValue));
//                        } else {
//                            HSSFRichTextString richString = new HSSFRichTextString(
//                                    textValue);
//                            HSSFFont font3 = workbook.createFont();
//                            font3.setColor(HSSFColor.BLUE.index);
//                            richString.applyFont(font3);
//                            cell.setCellValue(richString);
//                        }
//                    }
//                } catch (SecurityException | NoSuchMethodException | IllegalArgumentException
//                        | IllegalAccessException | InvocationTargetException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        try {
//            workbook.write(out);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    /**
     * 导出pdf
     * @param exportPdfDto 导出pdf实体类
     * @param out          输出流
     */
    public void exportPdf(ExportPdfDto exportPdfDto, OutputStream out){
        String fontPath = ExportUtil.class.getResource(FONT_RESOURCE_DIR).getPath();
        WriterProperties converterProperties = new WriterProperties();
        PdfDocument pdfDocument = new PdfDocument(new PdfWriter(out, converterProperties));
        pdfDocument.getCatalog().setLang(new PdfString(Charsets.UTF_8.name()));
        pdfDocument.setTagged();
        pdfDocument.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
        PageSize pageSize = PageSize.A4.rotate();
        pdfDocument.setDefaultPageSize(pageSize);
        ConverterProperties props = new ConverterProperties();
        FontProvider fp = new FontProvider();
        fp.addStandardPdfFonts();
        fp.addDirectory(fontPath);
        props.setFontProvider(fp);

        try {
            HtmlConverter.convertToPdf(new ByteArrayInputStream(exportPdfDto.getContent().getBytes(Charsets.UTF_8)), pdfDocument, props);
            pdfDocument.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String exportPdf(ExportPdfDto exportPdfDto){
        String pdfBasePath = ExportUtil.class.getResource(PDF_DIR).getPath();
        File files = new File(pdfBasePath);
        if(files.exists()){
            String pdfPath = pdfBasePath + exportPdfDto.getTitle() + ".pdf";
            try (FileOutputStream fileOutputStream = FileUtils.openOutputStream(new File(pdfPath))){
                this.exportPdf(exportPdfDto, fileOutputStream);
            }catch (IOException e) {
                e.printStackTrace();
            }
            return pdfPath;
        }
        return "";
    }

    /**
     * 导出zip
     * @param exportPdfDtoList exportPdfDtoList
     * @param out  OutputStream
     */
    public void exportZip(List<ExportPdfDto> exportPdfDtoList, OutputStream out){
        String pdfBasePath = ExportUtil.class.getResource(PDF_DIR).getPath();
        ZipOutputStream zipOutput = new ZipOutputStream(new BufferedOutputStream(out));
        zipOutput.setMethod(ZipOutputStream.DEFLATED);
        File files = new File(pdfBasePath);
        if(files.exists()){
            DataOutputStream os = null;
            try{
                for(ExportPdfDto exportPdfDto : exportPdfDtoList){
                    String pdfPath = this.exportPdf(exportPdfDto);
                    if(StringUtils.isNotBlank(pdfPath)){
                        zipOutput.putNextEntry(new ZipEntry(new File(pdfPath).getName()));
                        os = new DataOutputStream(zipOutput);
                        FileUtils.copyFile(new File(pdfPath), os);
                        zipOutput.closeEntry();
                        FileUtils.deleteQuietly(new File(pdfPath));
                    }
                }
            } catch (IOException e){
                e.printStackTrace();
            } finally {
                if(os != null){
                    try {
                        os.flush();
                        os.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
                try {
                    zipOutput.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

    public HttpServletResponse setExportResponse(int type, HttpServletResponse response, String title) {
        String contentType;
        switch(type){
            case ExportConstant.EXPORT_PDF : contentType = "application/pdf";break;
            case ExportConstant.EXPORT_EXCEL : contentType = "application/vnd.ms-excel";break;
            case ExportConstant.EXPORT_ZIP : contentType = "application/zip"; break;
            case ExportConstant.EXPORT_WORD :
            default: contentType = "application/msword"; break;
        }
        response.reset();
        response.setContentType(contentType + ";charset=utf-8");
        response.addHeader("Content-Disposition", title);
        return response;
    }

    /*public class AsianFontProvider extends XMLWorkerFontProvider {
        @Override
        public Font getFont(final String fontname, final String encoding,
                            final boolean embedded, final float size, final int style,
                            final BaseColor color) {
            try {
                BaseFont bf = BaseFont.createFont("C:/Windows/Fonts/msyhl.ttc", BaseFont.IDENTITY_H,
                        BaseFont.NOT_EMBEDDED);
                Font font = new Font(bf, size, style, color);
                font.setColor(color);
                return font;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return super.getFont(fontname, encoding, size, style);
        }
    }*/
}

